home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Eudora 1.3.1 / source / nickwin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  37.2 KB  |  1,457 lines  |  [TEXT/MPS ]

  1. #define FILE_NUM 3
  2. /* Copyright (c) 1990-1992 by the University of Illinois Board of Trustees */
  3. /* Copyright (c) 1992 by Qualcomm, Inc. */
  4. /**********************************************************************
  5.  * handling the alias panel
  6.  **********************************************************************/
  7. #pragma load EUDORA_LOAD
  8. #pragma segment NickWin
  9. Boolean VetoKey(short key);
  10.  
  11. /************************************************************************
  12.  * the structure for the alias window
  13.  ************************************************************************/
  14. typedef struct
  15. {
  16.     STEHandle exTE;
  17.     STEHandle noTE;
  18.     Rect exRect;
  19.     Rect noRect;
  20.     Rect niRect;
  21.     ControlHandle buttons[6];
  22.     ListHandle lHand;
  23.     Str31 partialSelect;
  24.     short selected;
  25.     short multiple;
  26.     long aOffset;
  27.     MyWindowPtr win;
  28.     Boolean isDirty;
  29. } AliasType, *AliasPtr, **AliasHandle;
  30. AliasHandle AliasGlobals;             /* for the alias window */
  31. #define ExTE (*AliasGlobals)->exTE
  32. #define NoTE (*AliasGlobals)->noTE
  33. #define ExRect (*AliasGlobals)->exRect
  34. #define NoRect (*AliasGlobals)->noRect
  35. #define NiRect (*AliasGlobals)->niRect
  36. #define Buttons (*AliasGlobals)->buttons
  37. #define RenameButton (*AliasGlobals)->buttons[0]
  38. #define NewButton (*AliasGlobals)->buttons[2]
  39. #define RemoveButton (*AliasGlobals)->buttons[3]
  40. #define ToButton (*AliasGlobals)->buttons[1]
  41. #define CcButton (*AliasGlobals)->buttons[4]
  42. #define BccButton (*AliasGlobals)->buttons[5]
  43. #define LHand (*AliasGlobals)->lHand
  44. #define PartialSelect (*AliasGlobals)->partialSelect
  45. #define Selected (*AliasGlobals)->selected
  46. #define Multiple (*AliasGlobals)->multiple
  47. #define AOffset (*AliasGlobals)->aOffset
  48. #define Win (*AliasGlobals)->win
  49. #define IsDirty (*AliasGlobals)->isDirty
  50. #define Scrolls (*AliasGlobals)->scrolls
  51. #define ExHBar (*AliasGlobals)->scrolls[0]
  52. #define ExVBar (*AliasGlobals)->scrolls[1]
  53. #define NoBar (*AliasGlobals)->scrolls[2]
  54. #define IsRecip(name) BinFindItemByName(GetMHandle(NEW_TO_HIER_MENU),name)
  55.  
  56. /************************************************************************
  57.  * private functions
  58.  ************************************************************************/
  59.     void AddAliasNames(void);
  60.     void AliasActivate(void);
  61.     void AliasClick(MyWindowPtr win, EventRecord *event);
  62.     void AliasKey(MyWindowPtr win, EventRecord *event);
  63.     Boolean AliasMenu(MyWindowPtr win, int menu, int item, short modifiers);
  64.     void AliasUpdate(MyWindowPtr win);
  65.     void AliasHelp(MyWindowPtr win,Point mouse);
  66.     void AliasCursor(Point mouse);
  67.     void DisplaySelectedAlias(void);
  68.     void SaveCurrentAlias(void);
  69.     void FlipRecip(void);
  70.     void RemoveNick(void);
  71.     void RenameNick(void);
  72.     void SetSTETo(STEHandle teh);
  73.     void ActOnAliasSelect(void);
  74.     void SelectAlias(int which);
  75.     Boolean AliasScroll(MyWindowPtr win,int h,int v);
  76.     void UnselectAlias(void);
  77.     void InsertTheAlias(short txeIndex,Boolean wantExpansion);
  78.     void AliasDidResize(MyWindowPtr win,Rect *oldContR);
  79.     void InvalAliasLeftSide(void);
  80.     void AliasSetGreys(void);
  81.     Boolean CanInsertAlias(void);
  82.     short ListPartial(ListHandle list,UPtr partial,short size,EventRecord*event);
  83.     Boolean CellMatch(ListHandle list,Point c,UPtr text);
  84.     void TETr(TEHandle teh,UPtr fromS, UPtr toS);
  85.     Boolean Tr(Handle text,UPtr fromS, UPtr toS);
  86.     void AliasButtons(MyWindowPtr win,ControlHandle button,long modifiers,short part);
  87.     void AliasTextChanged(MyWindowPtr win, TEHandle teh, int oldNl, int newNl,Boolean scroll);
  88.     Boolean BadNickname(UPtr candidate,UPtr veteran);
  89.     UPtr GetCurrentName(UPtr putItHere,Boolean *isRecip);
  90.     void PutCurrentName(UPtr what, Boolean isRecip);
  91.     void RemoveFromTo(UPtr name);
  92.     long FindAliasOffsetByIndex(short index);
  93.     Boolean NeedMenuCursor(Point mouse);
  94.     short GetDivLine(void);
  95.     Boolean AskNickname(UPtr name,Boolean *makeRecip,Handle addresses);
  96.     void AliasApp1(MyWindowPtr win,EventRecord *event);
  97.  
  98.  
  99. /************************************************************************
  100.  * OpenAliases - open the alias window
  101.  ************************************************************************/
  102. void OpenAliases(void)
  103. {
  104.     STEHandle teh;
  105.     Rect r,bounds;
  106.     Point cSize;
  107.     Handle grumble;
  108.     Str31 scratch;
  109.     short err,i;
  110.     
  111.     CycleBalls();
  112.     /*
  113.      * allocate the globals
  114.      */
  115.     if (AliasGlobals)
  116.     {
  117.         SelectWindow(Win);
  118.         return;
  119.     }
  120.     
  121.     if (!(AliasGlobals=NewZH(AliasType)))
  122.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  123.     
  124.     /*
  125.      * make sure the alias list is in memory
  126.      */
  127.     if (RegenerateAliases(&Aliases,ALIAS_CMD) || RegenerateAliases(&Notes,NOTE_CMD))
  128.     {
  129.         return;
  130.     }
  131.     AliasRefCount++;
  132.     
  133.     /*
  134.      * get the labels
  135.      */
  136.     LDRef(AliasGlobals);
  137.     
  138.     /*
  139.      * make the window
  140.      */
  141.     Win = GetNewMyWindow(ALIAS_WIND,nil,InFront,False,False);
  142.     UL(AliasGlobals);
  143.     if (!Win) goto fail;
  144.     Win->position = PositionPrefsTitle;
  145.     SetPort(Win);
  146.     r = Win->contR;
  147.     
  148.  
  149.     /*
  150.      * the add and remove buttons
  151.      */
  152.     for (i=0;i<sizeof(Buttons)/sizeof(Buttons[0]);i++)
  153.     {
  154.         if (!(grumble=GetNewControl(MAKE_TO_CNTL,Win)))
  155.             {err=MemError(); goto fail;}
  156.         else
  157.           {Buttons[i] = grumble;}
  158.     }
  159.     SetCTitle(RenameButton,GetRString(scratch,MBOX_RENAME));
  160.     SetCTitle(RemoveButton,GetRString(scratch,MBOX_REMOVE));
  161.     SetCTitle(NewButton,GetRString(scratch,MBOX_NEW));
  162.     SetCTitle(ToButton,GetRString(scratch,HEADER_LABEL_STRN+TO_HEAD));
  163.     SetCTitle(CcButton,GetRString(scratch,HEADER_LABEL_STRN+CC_HEAD));
  164.     SetCTitle(BccButton,GetRString(scratch,HEADER_LABEL_STRN+BCC_HEAD));
  165.  
  166.     
  167.     /*
  168.      * the alias list area
  169.      */
  170.     cSize.v = FontLead; cSize.h = GetRLong(ALIAS_A_WIDTH)-GROW_SIZE;
  171.     SetRect(&bounds,0,0,1,0);
  172.     LHand = LNew(&r,&bounds,cSize,0,Win,True,False,False,True);
  173.     if (!LHand) {WarnUser(MEM_ERR,MemError()); goto fail;}
  174.     (*LHand)->indent.v = FontAscent;
  175.     LDoDraw(False,LHand);
  176.     
  177.     
  178.     /*
  179.      * the alias expansion area
  180.      */
  181.     if (!(teh = NewSTE(Win,&r,True,True,True)))
  182.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  183.     (*(*teh)->te)->crOnly = -1;
  184.     ExTE = teh;
  185.     
  186.     
  187.     /*
  188.      * TERec for notes
  189.      */
  190.     if (!(teh = NewSTE(Win,&r,False,True,True)))
  191.         {WarnUser(MEM_ERR,MemError()); goto fail;}
  192.     NoTE = teh;
  193.     
  194.     
  195.     /*
  196.      * now, stick in the alias names
  197.      */
  198.     AddAliasNames();
  199.     LDoDraw(True,LHand);
  200.     
  201.     /*
  202.      * fill out the window record, and draw it
  203.      */
  204.     ((WindowPeek)Win)->windowKind = ALIAS_WIN;
  205.     Win->close = AliasClose;
  206.     Win->update = AliasUpdate;
  207.     Win->didResize = AliasDidResize;
  208.   Win->click = AliasClick;
  209.     Win->activate = AliasActivate;
  210.     Win->cursor = AliasCursor;
  211.     Win->dontControl = True;
  212.     Win->vPitch = FontLead;
  213.     Win->hPitch = FontWidth;
  214.     Win->textChanged = AliasTextChanged;
  215.     Win->button = AliasButtons;
  216.     Win->key = AliasKey;
  217.     Win->menu = AliasMenu;
  218.     Win->minSize.h = 5*72;
  219.     Win->minSize.v = 11*FontLead+4*GROW_SIZE;
  220.     Win->help = AliasHelp;
  221.     Win->app1 = AliasApp1;
  222.     SetSTETo(nil);
  223.     ShowMyWindow(Win);
  224.     AliasSetGreys();
  225.     UpdateMyWindow(Win);
  226.     if ((*LHand)->dataBounds.bottom) SelectAlias(1);
  227.     return;
  228.  
  229. fail:
  230.     AliasClose(Win);
  231. }
  232.  
  233. /************************************************************************
  234.  * 
  235.  ************************************************************************/
  236. void AliasApp1(MyWindowPtr win,EventRecord *event)
  237. {
  238.     if (win->ste) STEApp1(win->ste,event);
  239.     else
  240.     {
  241.         short page = RoundDiv((*LHand)->rView.bottom-(*LHand)->rView.top,(*LHand)->cellSize.v)-1;
  242.         switch(event->message & charCodeMask)
  243.         {
  244.             case homeChar:
  245.                 page = -INFINITY/2;
  246.                 break;
  247.             case endChar:
  248.                 page = INFINITY/2;
  249.                 break;
  250.             case pageUpChar:
  251.                 page *= -1;
  252.                 break;
  253.         }
  254.         LScroll(0,page,LHand);
  255.     }
  256. }
  257.  
  258. #define ALIASLAYOUT \
  259.     short aWidth=GetRLong(ALIAS_A_WIDTH);                                                                            \
  260.     short hi = (*CcButton)->contrlRect.bottom - (*CcButton)->contrlRect.top;    \
  261.   short wi, wi2 ,advance;                                                                                                        \
  262.     short h1,h2,h3,h4,v1,v2,v3,v4,v5;                                                                                    \
  263.     h1 = INSET+GROW_SIZE; h2 = h1+aWidth; h3 = h2+INSET;                                            \
  264.     h4 = Win->contR.right-INSET;                                                                                            \
  265.     v1 = 2*INSET+GROW_SIZE; v4 = Win->contR.bottom - 3*INSET - 2*hi;                    \
  266.     v2 = v1 + (GetRLong(ALIAS_ADDR_PC)*(v4-v1-3*INSET-GROW_SIZE))/100;                \
  267.     v3 = v2 + 2*INSET + GROW_SIZE;                                                                                        \
  268.     v5 = Win->contR.bottom - (Win->contR.bottom-v4-hi)/2-hi;                                    \
  269.     wi = (h2 - h1 - INSET)/2;                                                                                                    \
  270.     wi2 = (h4 - h3 - 2*INSET)/3;                                                                                            \
  271.     advance = wi2+INSET;
  272.  
  273. /************************************************************************
  274.  * AliasDidResize - size the alias window
  275.  ************************************************************************/
  276. void AliasDidResize(MyWindowPtr win,Rect *oldContR)
  277. {
  278. #define INSET 6
  279. #pragma unused(win,oldContR)
  280.     Rect r;
  281.     Point cSize;
  282.     ALIASLAYOUT
  283.     
  284.     SetPort(Win);
  285.  
  286.     /*
  287.      * buttons
  288.      */
  289.     MoveMyCntl(Win,RenameButton,h1,v4+INSET,wi,hi);
  290.     MoveMyCntl(Win,NewButton,h2-wi,v4+INSET,wi,hi);
  291.     MoveMyCntl(Win,RemoveButton,h1+(h2-h1-wi)/2,v4+2*INSET+hi,wi,hi);
  292.     MoveMyCntl(Win,ToButton,h3,v5,wi2,hi);
  293.     MoveMyCntl(Win,CcButton,h3+advance,v5,wi2,hi);
  294.     MoveMyCntl(Win,BccButton,h3+2*advance,v5,wi2,hi);
  295.  
  296.     /*
  297.      * the alias list area
  298.      */
  299.     cSize.v = FontLead; cSize.h = aWidth-GROW_SIZE;
  300.     SetRect(&r,h1,v1,h2,v4);
  301.     NiRect = r;
  302.     InsetRect(&r,1,1);
  303.     r.right -= GROW_SIZE;
  304.     LDoDraw(False,LHand);
  305.     (*LHand)->rView = r;
  306.     LSize(r.right-r.left,r.bottom-r.top,LHand);
  307.     LDoDraw(True,LHand);
  308.     
  309.     
  310.     /*
  311.      * the alias expansion area
  312.      */
  313.     SetRect(&r,h3,v1,h4,v2);
  314.     ExRect = r;
  315.     ResizeSTE(ExTE,&r);
  316.     
  317.     /*
  318.      * TERec for editing notes
  319.      */
  320.     SetRect(&r,h3,v3,h4,v4);
  321.     NoRect = r;
  322.     ResizeSTE(NoTE,&r);
  323.  
  324.     InvalRect(&Win->contR);
  325. }
  326.  
  327. #pragma segment Main
  328. /************************************************************************
  329.  * AliasClose - close the alias window
  330.  ************************************************************************/
  331. Boolean AliasClose(MyWindowPtr win)
  332. {
  333.     int which=WANNA_SAVE_SAVE;
  334.     if (!AliasGlobals) return(True);
  335.     if (win && win->isDirty)
  336.     {
  337.         which = WannaSave(win);
  338.         if (which==WANNA_SAVE_CANCEL || which==CANCEL_ITEM) return(False);
  339.         else if (which == WANNA_SAVE_SAVE && !SaveAliases()) return(False);
  340.     }
  341.  
  342.     if (LHand) LDispose(LHand);
  343.     if (ExTE) STEDispose(ExTE);
  344.     if (NoTE) STEDispose(NoTE);
  345.     DisposHandle(AliasGlobals);
  346.     AliasGlobals = nil;
  347.     if (win) win->txe = nil;
  348.     if (which==WANNA_SAVE_DISCARD)
  349.     {
  350.         AliasRefCount = 0;
  351.         DisposHandle(Aliases);
  352.         Aliases = nil;
  353.     }
  354.     else if (Aliases && AliasRefCount && !--AliasRefCount) HPurge(Aliases);
  355.     HPurge(Notes);
  356.     return(True);
  357. }
  358. #pragma segment AliasWin
  359.  
  360. /************************************************************************
  361.  * AliasUpdate - draw the alias window
  362.  ************************************************************************/
  363. void AliasUpdate(MyWindowPtr win)
  364. {
  365.     Rect r;
  366.     Str63 scratch;
  367.     ALIASLAYOUT
  368.     
  369.     TextFont(0);
  370.     TextSize(0);
  371.  
  372.     GetRString(scratch,ALIAS_A_LABEL);
  373.     MoveTo(h1,v1-INSET);
  374.     DrawString(scratch);
  375.  
  376.     GetRString(scratch,ALIAS_E_LABEL);
  377.     MoveTo(h3,v1-INSET);
  378.     DrawString(scratch);
  379.  
  380.     GetRString(scratch,ALIAS_N_LABEL);
  381.     MoveTo(h3,v3-INSET);
  382.     DrawString(scratch);
  383.  
  384.     FRAME_RECT(&NiRect);
  385.     if (Win->isActive && !win->ste) {r = NiRect; HotRect(&r,True);}
  386.     
  387.     STEUpdate(ExTE);
  388.     STEUpdate(NoTE);
  389.     TextFont(FontID);
  390.     TextSize(FontSize);
  391.     LUpdate(((GrafPtr)win)->visRgn,LHand);
  392.     OutlineControl(ToButton,win->isActive&&!InBG);
  393.         
  394.     if (!Win->isActive)
  395.     {
  396.         if (Selected&&!Multiple &&
  397.             (*LHand)->visible.top <= Selected && Selected <= (*LHand)->visible.bottom)
  398.         {
  399.             Point pt;
  400.             short v = (*LHand)->cellSize.v;
  401.             PolyHandle pH;
  402.             
  403.             pt.h = h1 - 4;
  404.             pt.v = v1 + ((2*(Selected-(*LHand)->visible.top)-1)*v)/2 + 1;
  405.             MoveTo(pt.h,pt.v);
  406.             if (pH=OpenPoly())
  407.             {
  408.                 Line(4-pt.h,(1-v)/2);
  409.                 Line(0,v-1);
  410.                 LineTo(pt.h,pt.v);
  411.                 ClosePoly();
  412.                 FillPoly(pH,&qd.black);
  413.                 KillPoly(pH);
  414.             }
  415.         }
  416.     }
  417. }
  418.  
  419. /************************************************************************
  420.  * AddAliasNames - put the names of the aliases into the list
  421.  ************************************************************************/
  422. void AddAliasNames(void)
  423. {
  424.     Str255 alias;
  425.     long spot;
  426.     short length;
  427.     long max=GetHandleSize(Aliases);
  428.  
  429.     for (spot=Selected=0; spot<max; spot+=CountAliasTotal(Aliases,spot))
  430.     {
  431.         Selected++;
  432.         length = CountAliasAlias(Aliases,spot);
  433.         PCopy(alias,(*Aliases)+spot);
  434.         (void) LAddRow(1,-1,LHand);
  435.         PutCurrentName(alias,IsRecip(alias));
  436.     }
  437.  
  438.     Selected = 0;
  439. }
  440.  
  441. /************************************************************************
  442.  *
  443.  ************************************************************************/
  444. void AliasesFixFont(void)
  445. {
  446.     TEFixup((*NoTE)->te); ResizeSTE(NoTE,nil);
  447.     TEFixup((*ExTE)->te); ResizeSTE(ExTE,nil);
  448.     TextFont(0);
  449.     TextSize(0);
  450. }
  451.  
  452. /************************************************************************
  453.  * ChooseAlias - pick an alias
  454.  ************************************************************************/
  455. void ChooseAlias(short which)
  456. {
  457.     GrafPtr oldPort;
  458.     
  459.     if (Selected==which && !Multiple) return;
  460.     
  461.     GetPort(&oldPort);
  462.     SetPort(Win);
  463.     UnselectAlias();
  464.     SelectAlias(which);
  465.     LAutoScroll(LHand);
  466.     SetPort(oldPort);
  467. }
  468.  
  469.  
  470. /************************************************************************
  471.  * SetSTETo - make sure the alias window's STE is where it should be
  472.  ************************************************************************/
  473. void SetSTETo(STEHandle ste)
  474. {
  475.     Rect r;
  476.     Point mouse;
  477.     if (Win->ste != ste)
  478.     {
  479.         if (Win->ste)
  480.             TEDeactivate((*(STEHandle)Win->ste)->te);
  481.         Win->ste = ste;
  482.         if (ste)
  483.         {
  484.           TEActivate((*ste)->te);
  485.             r=NiRect;HotRect(&r,False);
  486.         }
  487.         else
  488.         {
  489.           r = NiRect; HotRect(&r,True);
  490.         }
  491.     }
  492.     GetMouse(&mouse);
  493.     AliasCursor(mouse);
  494.     AliasSetGreys();
  495. }
  496.  
  497. /************************************************************************
  498.  * AliasClick - click in the alias window
  499.  ************************************************************************/
  500. void AliasClick(MyWindowPtr win, EventRecord *event)
  501. {
  502.     Rect exRect = ExRect;
  503.     Rect noRect = NoRect;
  504.     Rect niRect = NiRect;
  505.     Point mouse = event->where;
  506.  
  507.     GlobalToLocal(&mouse);
  508.     *PartialSelect = 0;
  509.     if (PtInRect(mouse,&exRect))
  510.     {
  511.         exRect.top = exRect.bottom-GROW_SIZE;
  512.         exRect.left = exRect.right-GROW_SIZE;
  513.         if (!PtInRect(mouse,&exRect))
  514.         {
  515.             if (Selected && !Multiple)
  516.             {
  517.                 SetSTETo(ExTE);
  518.                 STEClick(ExTE,event);
  519.             }
  520.         }
  521.     }
  522.     else if (PtInRect(mouse,&noRect))
  523.     {
  524.         if (Selected && !Multiple)
  525.         {
  526.             SetSTETo(NoTE);
  527.             STEClick(NoTE,event);
  528.         }
  529.     }
  530.     else
  531.     {
  532.         if (PtInRect(mouse,&niRect))
  533.         {
  534.             SetSTETo(nil);
  535.             if (NeedMenuCursor(mouse))
  536.                 FlipRecip();
  537.             else
  538.             {
  539.                 Boolean dblClick=MyLClick(mouse,event->modifiers,LHand);
  540.                 ActOnAliasSelect();
  541.                 if (dblClick && Selected)
  542. #ifdef I_HONESTLY_THINK_IT_COULD_BE_DONE_IN_ZINC
  543.                 {
  544.                     HiliteControl(ToButton,inButton);
  545.                     AliasButtons(Win,ToButton,event->modifiers,inButton);
  546.                     HiliteControl(ToButton,0);
  547.                 }
  548. #else
  549.                     FlipRecip();
  550. #endif
  551.             }
  552.         }
  553.         else HandleControl(mouse,win);
  554.     }
  555.     Win->hasSelection = MyWinHasSelection(win);
  556.     AliasSetGreys();
  557. }
  558.  
  559.  
  560. /************************************************************************
  561.  * DisplaySelectedAlias - display the text of an alias in ExTE
  562.  ************************************************************************/
  563. void DisplaySelectedAlias(void)
  564. {
  565.     long offset;
  566.     short length;
  567.     Handle addresses,notes;
  568.     Str63 name,isRecip;
  569.     short err;
  570.     
  571.     STESetText("",0,ExTE);
  572.     STESetText("",0,NoTE);
  573.     if (Selected && !Multiple)
  574.     {
  575.         length = 255;
  576.         AOffset = offset = FindAliasOffsetByIndex(Selected);
  577.         length =    CountAliasExpansion(Aliases,offset);
  578.         offset += CountAliasAlias(Aliases,offset)+1;
  579.         LDRef(Aliases);
  580.         addresses = SuckPtrAddresses((*Aliases)+offset+2,length,True);
  581.         UL(Aliases);
  582.         if (addresses)
  583.         {
  584.           SetHandleBig((*(*ExTE)->te)->hText,0);
  585.             FlattenListWith(addresses,'\n');
  586.           STEInstallText(addresses,ExTE);
  587.         }
  588.         GetCurrentName(name,&isRecip);
  589.         if ((offset=FindAliasFor(Notes,name+1,*name))>=0)
  590.         {
  591.             if (err=PtrToHand(LDRef(Notes)+offset+*name+3,¬es,
  592.                                                 CountAliasExpansion(Notes,offset)))
  593.                 WarnUser(MEM_ERR,err);
  594.             else
  595.             {
  596.                 Tr(notes,"\003","\n");
  597.                 STEInstallText(notes,NoTE);
  598.             }
  599.             UL(Notes);
  600.         }
  601.     }
  602. }
  603.  
  604. /************************************************************************
  605.  * FindAliasOffsetByIndex - find the offset of the nth alias
  606.  ************************************************************************/
  607. long FindAliasOffsetByIndex(short index)
  608. {
  609.     long offset;
  610.     offset = 0;
  611.     while (--index)
  612.     {
  613.         offset += CountAliasTotal(Aliases,offset);
  614.     }
  615.     return(offset);
  616. }
  617.  
  618.  
  619. /************************************************************************
  620.  * AliasActivate - handle things when the alias window is (de)activated
  621.  ************************************************************************/
  622. void AliasActivate(void)
  623. {
  624.   Rect r = NiRect;
  625.     LActivate(Win->isActive,LHand);
  626.     if (Selected && !Multiple) InvalAliasLeftSide();
  627.     OutlineControl(ToButton,Win->isActive&&!InBG);
  628.     if (Win->isActive)
  629.     {
  630.         AliasSetGreys();
  631.         *PartialSelect = 0;
  632.         if (!Win->ste) HotRect(&r,True);
  633.     }
  634.     else
  635.     {
  636.         SaveCurrentAlias();
  637.         HotRect(&r,False);
  638.     }
  639. }
  640.  
  641. /************************************************************************
  642.  * UnselectAlias - unselect the current alias
  643.  ************************************************************************/
  644. void UnselectAlias(void)
  645. {
  646.     Point c;
  647.     c.h = c.v = 0;
  648.     if (LGetSelect(True,&c,LHand))
  649.     {
  650.         InvalAliasLeftSide();
  651.         SetSTETo(nil);
  652.         do
  653.         {
  654.             LSetSelect(False,c,LHand);
  655.         }
  656.         while (LGetSelect(True,&c,LHand));
  657.     }
  658. }
  659.  
  660. /************************************************************************
  661.  * SelectAlias - select a particular alias cell
  662.  ************************************************************************/
  663. void SelectAlias(int which)
  664. {
  665.     Point c;
  666.     
  667.     c.h = 0; c.v = which-1;
  668.     LSetSelect(True,c,LHand);
  669.     ActOnAliasSelect();
  670. }
  671.  
  672. /************************************************************************
  673.  * ActOnAliasSelect - react to the selection of an alias cell
  674.  ************************************************************************/
  675. void ActOnAliasSelect()
  676. {
  677.     short which, next;
  678.     
  679.     which = Next1Selected(0,LHand);
  680.     next = Next1Selected(which,LHand);
  681.     
  682.     if (Multiple && next) return;    /* still a multiple selection */
  683.     if (which==Selected && !next) return;    /* same single selection */
  684.     SaveCurrentAlias();
  685.     Selected = which;
  686.     Multiple = next;
  687.     DisplaySelectedAlias();
  688.     SetSTETo(nil);
  689.     InvalAliasLeftSide();
  690.     AliasSetGreys();
  691. }
  692.  
  693. /************************************************************************
  694.  * InvalAliasLeftSide - invalidate the area to the left of the alias
  695.  * selection rectangle
  696.  ************************************************************************/
  697. void InvalAliasLeftSide(void)
  698. {
  699.     Rect r=NiRect;
  700.     SAVE_PORT;
  701.     SetPort(Win);
  702.     r.right = r.left-4;
  703.     r.left = 0;
  704.     InvalRect(&r);
  705.     REST_PORT;
  706. }
  707.  
  708. /************************************************************************
  709.  * AliasSetGreys - set the greyness of controls
  710.  ************************************************************************/
  711. void AliasSetGreys(void)
  712. {
  713.     Boolean oldTo=(*ToButton)->contrlRfCon=='GREY';
  714.     SetGreyControl(RemoveButton,!Selected);
  715.     SetGreyControl(RenameButton,!Selected || Multiple);
  716.     SetGreyControl(ToButton,!Selected);
  717.     SetGreyControl(CcButton,!Selected);
  718.     SetGreyControl(BccButton,!Selected);
  719.     if (oldTo!=((*ToButton)->contrlRfCon=='GREY'))
  720.     {
  721.         Rect r = (*ToButton)->contrlRect;
  722.         InsetRect(&r,-4,-4);
  723.         InvalRect(&r);
  724.     }
  725. }
  726.  
  727. /************************************************************************
  728.  *
  729.  ************************************************************************/
  730. Boolean CanInsertAlias(void)
  731. {
  732.     MyWindowPtr win;
  733.     return((win=(((WindowPeek)FrontWindow())->nextWindow)) && IsMyWindow(win) &&
  734.                     win->qWindow.windowKind==COMP_WIN);
  735. }
  736.  
  737. /************************************************************************
  738.  * AliasKey - handle a keystroke in the alias window
  739.  ************************************************************************/
  740. void AliasKey(MyWindowPtr win, EventRecord *event)
  741. {
  742.     short key = (event->message & 0xff);
  743.     
  744.     if (win->ste)
  745.         switch (key)
  746.         {
  747.             default:
  748.                 if (!(event->modifiers&cmdKey)) TESomething(win,TEKEY,key,event->modifiers);
  749.                 break;
  750.             case enterChar:
  751.                 SaveCurrentAlias();
  752.                 break;
  753.             case tabChar:
  754.                 if (win->ste==nil)
  755.                     SetSTETo((event->modifiers&shiftKey)?NoTE:ExTE);
  756.                 if (win->ste==ExTE)
  757.                     SetSTETo((event->modifiers&shiftKey)?nil:NoTE);
  758.                 else
  759.                     SetSTETo((event->modifiers&shiftKey)?ExTE:nil);
  760.                 if (win->ste) NoScrollTESetSelect(0,INFINITY,(*(STEHandle)win->ste)->te);
  761.                 break;
  762.         }
  763.     else
  764.         switch (key)
  765.         {
  766.             case upArrowChar:
  767.                 ChooseAlias(Selected>1 ? Selected-1 : (*LHand)->dataBounds.bottom);
  768.                 break;
  769.             case downArrowChar:
  770.                 ChooseAlias(Selected<(*LHand)->dataBounds.bottom ? Selected+1 : 1);
  771.                 break;
  772.             case returnChar:
  773.             case enterChar:
  774.                 if (Selected)
  775.                 {
  776.                     SaveCurrentAlias();
  777.                     HiliteControl(ToButton,inButton);
  778.                     AliasButtons(win,ToButton,event->modifiers,inButton);
  779.                     HiliteControl(ToButton,0);
  780.                 }
  781.                 break;
  782.             case tabChar:
  783.                 if (Selected && !Multiple)
  784.                 {
  785.                     SetSTETo(event->modifiers&shiftKey ? NoTE : ExTE);
  786.                     NoScrollTESetSelect(0,INFINITY,(*(STEHandle)win->ste)->te);
  787.                 }
  788.                 break;
  789.             default:
  790.                 if (!(event->modifiers&cmdKey))
  791.                 {
  792.                     short which;
  793.                     LDRef(AliasGlobals);
  794.                     which =
  795.                         ListPartial(LHand,PartialSelect,sizeof(PartialSelect),event)+1;
  796.                     UL(AliasGlobals);
  797.                     if (which>0) ChooseAlias(which);
  798.                 }
  799.         }
  800.     Win->hasSelection = MyWinHasSelection(win);
  801. }
  802.  
  803. /************************************************************************
  804.  * ListPartial
  805.  ************************************************************************/
  806. short ListPartial(ListHandle list,UPtr partial,short size,EventRecord*event)
  807. {
  808.     Point c;
  809.     short key = event->message&charCodeMask;
  810.     static long oldTicks=0;
  811.     
  812.     c.h = c.v = 0;
  813.     if (key==backSpace || key==escChar)
  814.     {
  815.         *partial = 0;
  816.         return(-1);
  817.     }
  818.     
  819.     if (event->when - oldTicks > GetRLong(PARTIAL_TICKS)) *partial = 0;
  820.     
  821.     oldTicks = event->when;
  822.     if (*partial && LGetSelect(True,&c,list) && !CellMatch(list,c,partial))
  823.      c.h = c.v = 0;
  824.  
  825.     if (*partial<size-1) PCatC(partial,key);
  826.     partial[*partial+1] = 0;
  827.     for (;c.v<(*list)->dataBounds.bottom;c.v++)
  828.         if (CellMatch(list,c,partial)) return(c.v);
  829.         
  830.     return(-1);
  831. }
  832.  
  833. /************************************************************************
  834.  *
  835.  ************************************************************************/
  836. Boolean CellMatch(ListHandle list,Point c,UPtr text)
  837. {
  838.     Str63 name;
  839.     short len=sizeof(name)-1;
  840.     
  841.     LGetCell(name+1,&len,c,list);
  842.     if (len-1<*text) return(0);
  843.     name[len] = 0;
  844.     return(!striscmp(name+2,text+1));
  845. }
  846.  
  847. /************************************************************************
  848.  * TETr - translate text in a TERec
  849.  ************************************************************************/
  850. void TETr(TEHandle teh,UPtr fromS, UPtr toS)
  851. {
  852.     if (Tr((*teh)->hText,fromS,toS))
  853.     {
  854.         SAVE_PORT;
  855.         TECalText(teh);
  856.         INVAL_RECT(&(*teh)->viewRect);
  857.         TESelView(teh);
  858.         REST_PORT;
  859.     }
  860. }
  861.  
  862.  
  863. /************************************************************************
  864.  * Tr - translate text in a handle
  865.  ************************************************************************/
  866. Boolean Tr(Handle text,Uptr fromS, Uptr toS)
  867. {
  868.     UPtr end,spot;
  869.     Boolean did=False;
  870.     short fromChar,toChar;
  871.     long size = GetHandleSize(text);
  872.     
  873.     end = *text+size;
  874.     for (;*fromS;fromS++,toS++)
  875.     {
  876.         fromChar = *fromS;
  877.         toChar = *toS;
  878.         for (spot= *text;spot<end;spot++)
  879.             if (*spot==fromChar)
  880.             {
  881.                 did = True;
  882.                 *spot = toChar;
  883.             }
  884.     }
  885.     return(did);
  886. }
  887.  
  888. /************************************************************************
  889.  * AliasCursor - set the cursor properly for the alias window
  890.  ************************************************************************/
  891. void AliasCursor(Point mouse)
  892. {
  893.     Rect r;
  894.     short cell, divLine;
  895.     short cursor;
  896.     
  897.     r = NiRect; r.right -= GROW_SIZE;
  898.     if (CursorInRect(mouse,r,MouseRgn))
  899.     {
  900.         cursor = plusCursor;    /* probably */
  901.         cell=InWhich1Cell(mouse,LHand);
  902.         r.top += Win->vPitch * (cell-(*LHand)->visible.top-1);
  903.         r.bottom = r.top+Win->vPitch;
  904.         divLine = GetDivLine();
  905.         if (mouse.h<divLine)
  906.         {
  907.             r.right = divLine;
  908.             if (Cell1Selected(cell,LHand)) cursor = MENU_CURS;
  909.         }
  910.         else
  911.             r.left = divLine;
  912.         SetMyCursor(cursor);
  913.         RectRgn(MouseRgn,&r);
  914.     }
  915.     else if (CursorInRect(mouse,ExRect,MouseRgn))
  916.     {
  917.         if (Selected && !Multiple) STECursor(ExTE); else SetMyCursor(arrowCursor);
  918.     }
  919.     else if (CursorInRect(mouse,NoRect,MouseRgn))
  920.     {
  921.         if (Selected && !Multiple) STECursor(NoTE); else SetMyCursor(arrowCursor);
  922.     }
  923.     else
  924.         SetMyCursor(arrowCursor);
  925. }
  926.  
  927. /************************************************************************
  928.  * AliasButtons - handle a click on a button
  929.  ************************************************************************/
  930. void AliasButtons(MyWindowPtr win,ControlHandle button,long modifiers,short part)
  931. {
  932. #pragma unused(win)
  933.     if (part!=inButton) return;
  934.     if (button==NewButton)
  935.         NewNick(nil);
  936.     else if (button==RenameButton)
  937.         RenameNick();
  938.     else if (button==RemoveButton)
  939.         RemoveNick();
  940.     else
  941.     {
  942.         if (Selected)
  943.         {
  944.             SaveCurrentAlias();
  945.             if (button==ToButton)
  946.             {
  947.                 InsertTheAlias(TO_HEAD-1,(modifiers&optionKey)!=0);
  948.                 if (FrontWindow()==Win) SelectWindow(Win->qWindow.nextWindow);
  949.             }
  950.             else if (button==CcButton)
  951.                 InsertTheAlias(CC_HEAD-1,(modifiers&optionKey)!=0);
  952.             else if (button==BccButton)
  953.                 InsertTheAlias(BCC_HEAD-1,(modifiers&optionKey)!=0);
  954.         }
  955.     }
  956. }
  957.  
  958. /************************************************************************
  959.  * RemoveNick - get rid of a nickname
  960.  ************************************************************************/
  961. void RemoveNick(void)
  962. {
  963.     short s;
  964.     Str63 name;
  965.     Boolean isRecip;
  966.     
  967.     for (s=Next1Selected(0,LHand);s;s=Next1Selected(s-1,LHand))
  968.     {
  969.         Selected = s;
  970.         GetCurrentName(name,&isRecip);
  971.         LDelRow(1,s-1,LHand);
  972.         if (isRecip) RemoveFromTo(name);
  973.         RemoveAlias(Aliases,name);
  974.         RemoveAlias(Notes,name);
  975.     }
  976.     Selected = -1;
  977.     IsDirty = False;
  978.     Win->isDirty = True;
  979.     SelectAlias(0);
  980. }
  981.  
  982. /************************************************************************
  983.  * RemoveFromTo - remove something from the recipient menus
  984.  ************************************************************************/
  985. void RemoveFromTo(UPtr name)
  986. {
  987.     short menu,item;
  988.     
  989.     if (item=BinFindItemByName(GetMHandle(NEW_TO_HIER_MENU),name))
  990.     {
  991.         for (menu=NEW_TO_HIER_MENU;menu<=INSERT_TO_HIER_MENU;menu++)
  992.             DelMenuItem(GetMHandle(menu),item);
  993.         ToMenusChanged();
  994.     }
  995. }
  996.  
  997. /************************************************************************
  998.  * RenameNick - rename a nickname
  999.  ************************************************************************/
  1000. void RenameNick(void)
  1001. {
  1002.     Str63 name;
  1003.     Boolean makeRecip,wasRecip;
  1004.     
  1005.     GetCurrentName(name,&wasRecip);
  1006.     makeRecip = wasRecip;
  1007.     if (AskNickname(name,&makeRecip,nil))
  1008.     {
  1009.         UpdateMyWindow(Win);
  1010.         PutCurrentName(name,makeRecip);
  1011.         IsDirty = Win->isDirty = True;
  1012.         SaveCurrentAlias();
  1013.     }
  1014. }
  1015.  
  1016. /************************************************************************
  1017.  * GetCurrentName - get the currently selected nickname
  1018.  ************************************************************************/
  1019. UPtr GetCurrentName(UPtr putItHere,Boolean *isRecip)
  1020. {
  1021.     Point c;
  1022.     short len=31;
  1023.     
  1024.     if (!Selected)
  1025.         *putItHere = 0;
  1026.     else
  1027.     {
  1028.         c.h = 0; c.v = Selected-1;
  1029.         LGetCell(putItHere,&len,c,LHand);
  1030.         *isRecip = (*putItHere==bulletChar);
  1031.         *putItHere = len-1;
  1032.         putItHere[len] = 0;    /* null terminate, in case anybody cares */
  1033.     }
  1034.     return(putItHere);
  1035. }
  1036.  
  1037. /************************************************************************
  1038.  * PutCurrentName - put something into the currently selected nickname
  1039.  ************************************************************************/
  1040. void PutCurrentName(UPtr what,Boolean isRecip)
  1041. {
  1042.     Point c;
  1043.     Str31 scratch;
  1044.     
  1045.     PCopy(scratch,what);
  1046.     c.h = 0; c.v = Selected-1;
  1047.     *scratch = isRecip ? bulletChar : nbSpaceChar;
  1048.     LSetCell(scratch,*what+1,c,LHand);
  1049. }
  1050.  
  1051. /************************************************************************
  1052.  * NewNick - create a new alias for the user
  1053.  ************************************************************************/
  1054. void NewNick(Handle addresses)
  1055. {
  1056.     Point c;
  1057.     Str63 name;
  1058.     Boolean makeRecip=False;
  1059.     
  1060.     *name = 0;
  1061.     if (!AliasGlobals && RegenerateAliases(&Aliases,ALIAS_CMD)) return;
  1062.     AliasRefCount++;
  1063.     if (AskNickname(name,&makeRecip,addresses))
  1064.     {
  1065.         long addrSize = addresses ? GetHandleSize(addresses) : 0;
  1066.         if (addrSize) FlattenListWith(addresses,',');
  1067.         if (AliasGlobals) {UpdateMyWindow(Win);SaveCurrentAlias();}
  1068.         AddAlias(Aliases,name,addresses);
  1069.         if (makeRecip) AddStringAsTo(name);
  1070.         
  1071.         if (AliasGlobals)
  1072.         {
  1073.             UnselectAlias();
  1074.             c.v = LAddRow(1,INFINITY,LHand);
  1075.             c.h = 0;
  1076.             LSetSelect(True,c,LHand);
  1077.             LAutoScroll(LHand);
  1078.             SelectAlias(c.v+1);
  1079.             PutCurrentName(name,makeRecip);
  1080.             Win->isDirty = IsDirty = True;
  1081.             if (FrontWindow()==Win && !addrSize)
  1082.                 SetSTETo(ExTE);
  1083.         }
  1084.         else
  1085.             SaveAliases();
  1086.     }
  1087.     AliasRefCount--;
  1088. }
  1089.  
  1090. /************************************************************************
  1091.  * AskNickname - ask the user for a new nickname.  Returns True if successful
  1092.  ************************************************************************/
  1093. Boolean AskNickname(UPtr name,Boolean *makeRecip,Handle addresses)
  1094. {
  1095. #pragma unused(addresses)
  1096.     Str255 workingName;
  1097.     DialogPtr dgPtr;
  1098.     short item;
  1099.     SAVE_PORT;
  1100.     
  1101.     ThirdCenterDialog(NEW_NICK_DLOG);
  1102.     if ((dgPtr = GetNewDialog(NEW_NICK_DLOG,nil,InFront))==nil)
  1103.         return(False);
  1104.         
  1105.     PCopy(workingName,name);
  1106.     SetDItemState(dgPtr,NEW_NICK_RECIP,*makeRecip);
  1107.     SetDIText(dgPtr,NEW_NICK_NAME,workingName);
  1108.     ShowWindow(dgPtr);
  1109.     HiliteButtonOne(dgPtr);
  1110.     do
  1111.     {
  1112.         SelIText(dgPtr,NEW_NICK_NAME,0,INFINITY);
  1113.         ModalDialog(DlgFilter,&item);
  1114.         if (item==NEW_NICK_RECIP)
  1115.             SetDItemState(dgPtr,NEW_NICK_RECIP,!GetDItemState(dgPtr,NEW_NICK_RECIP));
  1116.         else
  1117.             GetDIText(dgPtr,NEW_NICK_NAME,workingName);
  1118.     }
  1119.     while (item==NEW_NICK_RECIP || item==1 && BadNickname(workingName,name));
  1120.     
  1121.     if (item==1)
  1122.     {
  1123.         *makeRecip = GetDItemState(dgPtr,NEW_NICK_RECIP);
  1124.         PCopy(name,workingName);
  1125.     }
  1126.     DisposDialog(dgPtr);
  1127.     REST_PORT;
  1128.     return(item==1);
  1129. }
  1130.  
  1131. /************************************************************************
  1132.  * BadNickname - is the nickname defective?
  1133.  ************************************************************************/
  1134. Boolean BadNickname(UPtr candidate,UPtr veteran)
  1135. {
  1136.     Str31 verboten;
  1137.     UPtr spot,end,key;
  1138.  
  1139.     if (!*candidate) return(True);
  1140.     if (*candidate>MAX_NICKNAME)
  1141.     {
  1142.         WarnUser(ALIAS_TOO_LONG,MAX_NICKNAME);
  1143.         return(True);
  1144.     }
  1145.     if (*veteran && EqualString(candidate,veteran,False,True)) return(False);
  1146.     GetRString(verboten,ALIAS_VERBOTEN);
  1147.     end = verboten+*verboten+1;
  1148.     for (key=candidate+1;key<=candidate+*candidate;key++)
  1149.         for (spot=verboten+1;spot<end;spot++)
  1150.             if (*spot==*key)
  1151.             {
  1152.                 WarnUser(WARN_VERBOTEN,0);
  1153.                 return(True);
  1154.             }
  1155.     if (FindExpansionFor(Aliases,candidate+1,*candidate))
  1156.     {
  1157.         WarnUser(NICK_IN_USE,0);
  1158.         return(True);
  1159.     }
  1160.     return(False);
  1161. }
  1162.  
  1163. /************************************************************************
  1164.  * SaveCurrentAlias - save the expansion
  1165.  ************************************************************************/
  1166. void SaveCurrentAlias(void)
  1167. {
  1168.     Str63 newName,oldName;
  1169.     short maxAlias=GetRLong(BUFFER_SIZE)-40;
  1170.     UHandle addresses,text;
  1171.     Boolean isRecip;
  1172.     
  1173.     SetSTETo(nil);
  1174.     if (IsDirty)
  1175.     {
  1176.         GetCurrentName(newName,&isRecip);
  1177.         PCopy(oldName,(*Aliases)+AOffset);
  1178.         
  1179.         /*
  1180.          * fix the expansion
  1181.          */
  1182.         text = (*(*ExTE)->te)->hText;
  1183.         if (HandToHand(&text)) {WarnUser(COULDNT_MOD_ALIAS,MemError());return;}
  1184.         Tr(text,"\n",",");
  1185.         if (addresses=SuckAddresses(text,GetHandleSize(text),False)) DisposHandle(addresses);
  1186.         ReplaceAlias(Aliases,oldName,newName,text);
  1187.         DisposHandle(text);
  1188.         
  1189.         /*
  1190.          * fix the notes
  1191.          */
  1192.         text = (*(*NoTE)->te)->hText;
  1193.         if (HandToHand(&text)) {WarnUser(COULDNT_MOD_ALIAS,MemError());return;}
  1194.         if (GetHandleSize(text))
  1195.         {
  1196.             Tr(text,"\n","\003");
  1197.             if (FindAliasFor(Notes,oldName+1,*oldName)>=0)
  1198.                 ReplaceAlias(Notes,oldName,newName,text);
  1199.             else
  1200.                 AddAlias(Notes,newName,text);
  1201.         }
  1202.         else
  1203.             RemoveAlias(Notes,oldName);
  1204.         
  1205.         /*
  1206.          * change recip menu
  1207.          */
  1208.         RemoveFromTo(oldName);
  1209.         if (isRecip)
  1210.             AddStringAsTo(newName);
  1211.         IsDirty = False;
  1212.         NukeUndo(Win);
  1213.     }
  1214. }
  1215.  
  1216. /************************************************************************
  1217.  * 
  1218.  ************************************************************************/
  1219. void AliasTextChanged(MyWindowPtr win, TEHandle teh, int oldNl, int newNl, Boolean scroll)
  1220. {
  1221. #pragma unused(oldNl,newNl,scroll)
  1222.     IsDirty = True;
  1223.     if ((*ExTE)->te==teh) SetSTETo(ExTE);
  1224.     else if ((*NoTE)->te==teh) SetSTETo(NoTE);
  1225.     else return;
  1226.     STETextChanged(win->ste);
  1227. }
  1228.  
  1229. /************************************************************************
  1230.  * InsertTheAlias - insert the given alias in the window below us
  1231.  ************************************************************************/
  1232. void InsertTheAlias(short txeIndex,Boolean wantExpansion)
  1233. {
  1234.     MyWindowPtr win;
  1235.     GrafPtr oldPort;
  1236.     short s=0;
  1237.     
  1238.     win = ((WindowPeek)FrontWindow())->nextWindow;
  1239.     if (!IsMyWindow(win) || win->qWindow.windowKind!=COMP_WIN ||
  1240.       SumOf(Win2MessH(win))->state==SENT)
  1241.     {
  1242.         win = DoComposeNew(0);
  1243.     }
  1244.     
  1245.     if (IsMyWindow(win) && win->qWindow.windowKind==COMP_WIN &&
  1246.       SumOf(Win2MessH(win))->state!=SENT)
  1247.     {
  1248.         TEHandle oldTXE=win->txe;
  1249.         MessHandle messH = Win2MessH(win);
  1250.         GetPort(&oldPort);
  1251.         SetPort(win);
  1252.         win->txe = (*messH)->txes[txeIndex];
  1253.         TESetSelect(INFINITY,INFINITY,win->txe);
  1254.         while (s=Next1Selected(s,LHand))
  1255.         {
  1256.             InsertCommaIfNeedBe(win);
  1257.             InsertAlias(win,FindAliasOffsetByIndex(s),wantExpansion);
  1258.       }
  1259.         win->txe = oldTXE;
  1260.         ShowMyWindow(win);
  1261.         SetPort(oldPort);
  1262.     }
  1263. }
  1264.  
  1265. /************************************************************************
  1266.  * AliasMenu - menu choice in the alias window
  1267.  ************************************************************************/
  1268. Boolean AliasMenu(MyWindowPtr win, int menu, int item, short modifiers)
  1269. {
  1270. #pragma unused(modifiers)
  1271.     Boolean res;
  1272.     short oldSel,s,err;
  1273.     Handle addresses;
  1274.     Str63 name;
  1275.     Boolean isRecip;
  1276.     Point pt;
  1277.     
  1278.     switch (menu)
  1279.     {
  1280.         case FILE_MENU:
  1281.             switch(item)
  1282.             {
  1283.                 case FILE_SAVE_ITEM:
  1284.                     SaveAliases();
  1285.                     return(True);
  1286.                     break;
  1287.             }
  1288.             break;
  1289.         case SPECIAL_MENU:
  1290.             switch(item)
  1291.             {
  1292.                 case SPECIAL_MAKE_NICK_ITEM:
  1293.                     oldSel = Selected;
  1294.                     addresses = NuHandle(0);
  1295.                     for (s=Next1Selected(0,LHand);s;s=Next1Selected(s,LHand))
  1296.                     {
  1297.                         Selected = s;
  1298.                         GetCurrentName(name,&isRecip);
  1299.                         if (err = PtrAndHand(name,addresses,*name+2))
  1300.                             {WarnUser(MEM_ERR,err); break;}
  1301.                     }
  1302.                     Selected = oldSel;
  1303.                     if (!err)
  1304.                     {
  1305.                         PtrAndHand("",addresses,1);    /* if we can't get one byte, to hell with it */
  1306.                         NewNick(addresses);
  1307.                     }
  1308.                     if (addresses) DisposHandle(addresses);
  1309.                     break;
  1310.             }
  1311.             break;
  1312.         case EDIT_MENU:
  1313.             if (win->ste)
  1314.             {
  1315.                 res = TESomething(win,item,0,modifiers);
  1316.                 Win->hasSelection = MyWinHasSelection(win);
  1317.                 return(res);
  1318.             }
  1319.             else if (item==EDIT_SELECT_ITEM)
  1320.             {
  1321.                 s = (*LHand)->dataBounds.bottom;
  1322.                 for (pt.h=pt.v=0;pt.v<s;pt.v++) LSetSelect(True,pt,LHand);
  1323.             }
  1324.             break;
  1325.     }
  1326.     return(False);
  1327. }
  1328.  
  1329. /************************************************************************
  1330.  * FlipRecip - change the recipient state of some nicknames
  1331.  ************************************************************************/
  1332. void FlipRecip(void)
  1333. {
  1334.     Str63 name;
  1335.     Boolean isRecip,makeRecip;
  1336.     short oldSel = Selected;
  1337.     short s=0;
  1338.     
  1339.     GetCurrentName(name,&isRecip);
  1340.     makeRecip = !isRecip;
  1341.     while(s=Next1Selected(s,LHand))
  1342.     {
  1343.         Selected = s;
  1344.         GetCurrentName(name,&isRecip);
  1345.         if (isRecip != makeRecip)
  1346.         {
  1347.             PutCurrentName(name,makeRecip);
  1348.             if (makeRecip) AddStringAsTo(name);
  1349.             else RemoveFromTo(name);
  1350.         }
  1351.     }
  1352. }
  1353.  
  1354. /************************************************************************
  1355.  * NeedMenuCursor - do we need the menu-change cursor?
  1356.  ************************************************************************/
  1357. Boolean NeedMenuCursor(Point mouse)
  1358. {
  1359.     return (mouse.h<GetDivLine() &&
  1360.         Cell1Selected(InWhich1Cell(mouse,LHand),LHand));
  1361. }
  1362.  
  1363. /************************************************************************
  1364.  * GetDivLine - calculate the dividing line between the recip and nickname
  1365.  *    areas.
  1366.  ************************************************************************/
  1367. short GetDivLine(void)
  1368. {
  1369.     return((*LHand)->rView.left+Win->hPitch+(*LHand)->indent.h);
  1370. }
  1371.  
  1372. #pragma segment Main
  1373. /************************************************************************
  1374.  * AliasWinIsOpen - is the alias window open?
  1375.  ************************************************************************/
  1376. Boolean AliasWinIsOpen(void)
  1377. {
  1378.     return(AliasGlobals!=nil);
  1379. }
  1380.  
  1381. /************************************************************************
  1382.  * AliasWinGonnaSave - we're going to save the nickname list
  1383.  ************************************************************************/
  1384. void AliasWinGonnaSave(void)
  1385. {
  1386.     if (AliasGlobals) SaveCurrentAlias();
  1387. }
  1388.  
  1389. /************************************************************************
  1390.  * AliasWinDidSave - we just saved the nickname list
  1391.  ************************************************************************/
  1392. void AliasWinDidSave(void)
  1393. {
  1394.     if (AliasGlobals) Win->isDirty = False;
  1395. }
  1396.  
  1397. /************************************************************************
  1398.  * CanMakeNick - should we enable the "make nickname" item?
  1399.  ************************************************************************/
  1400. Boolean CanMakeNick(void)
  1401. {
  1402.   return(AliasGlobals&&Selected&&Multiple);
  1403. }
  1404.  
  1405. #pragma segment Balloon
  1406. /************************************************************************
  1407.  * AliasHelp - help for the alias window
  1408.  ************************************************************************/
  1409. void AliasHelp(MyWindowPtr win,Point mouse)
  1410. {
  1411. #pragma unused(win)
  1412.     Rect r;
  1413.     short c;
  1414.     short hnum=1;
  1415.     Boolean canInsert = CanInsertAlias();
  1416.     
  1417.  
  1418.     r = NoRect;
  1419.     if (PtInRect(mouse,&r))
  1420.     {
  1421.         if (Selected && !Multiple) hnum++;
  1422.         goto display;
  1423.     }
  1424.     hnum += 2;
  1425.     
  1426.     r = ExRect;
  1427.     if (PtInRect(mouse,&r))
  1428.     {
  1429.         if (Selected && !Multiple) hnum++;
  1430.         goto display;
  1431.     }
  1432.     hnum += 2;
  1433.     
  1434.     r = NiRect;
  1435.     if (PtInRect(mouse,&r))
  1436.     {
  1437.         if (!canInsert) hnum++;
  1438.         goto display;
  1439.     }
  1440.     hnum+=2;
  1441.     
  1442.     for (c=0;c<sizeof(Buttons)/sizeof(ControlHandle);c++,hnum+=3)
  1443.         if (PtInRect(mouse,&(*Buttons[c])->contrlRect))
  1444.         {
  1445.             r = (*Buttons[c])->contrlRect;
  1446.             if ((*Buttons[c])->contrlRfCon=='GREY') goto display;
  1447.             hnum++;
  1448.             if (!canInsert) hnum++;
  1449.             goto display;
  1450.         }
  1451.  
  1452.     return;
  1453.     
  1454.     display:
  1455.         HelpRect(&r,NICK_HELP_STRN+hnum,100);
  1456. }
  1457.